#pragma once

#define BLUEGRASS_META_EXPAND(X) X

#define BLUEGRASS_META_GET_NTH_ARG(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, NAME, ...) NAME

#define BLUEGRASS_META_FE0(MAC, ...)
#define BLUEGRASS_META_FE1(MAC,  A, B) MAC(A, B)
#define BLUEGRASS_META_FE2(MAC,  A, B, ...) MAC(A, B) BLUEGRASS_META_FE1(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE3(MAC,  A, B, ...) MAC(A, B) BLUEGRASS_META_FE2(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE4(MAC,  A, B, ...) MAC(A, B) BLUEGRASS_META_FE3(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE5(MAC,  A, B, ...) MAC(A, B) BLUEGRASS_META_FE4(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE6(MAC,  A, B, ...) MAC(A, B) BLUEGRASS_META_FE5(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE7(MAC,  A, B, ...) MAC(A, B) BLUEGRASS_META_FE6(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE8(MAC,  A, B, ...) MAC(A, B) BLUEGRASS_META_FE7(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE9(MAC,  A, B, ...) MAC(A, B) BLUEGRASS_META_FE8(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE10(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE9(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE11(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE10(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE12(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE11(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE13(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE12(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE14(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE13(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE15(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE14(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE16(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE15(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE17(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE16(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE18(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE17(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE19(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE18(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE20(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE19(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE21(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE20(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE22(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE21(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE23(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE22(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE24(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE23(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE25(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE24(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE26(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE25(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE27(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE26(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE28(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE27(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE29(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE28(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE30(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE29(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE31(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE30(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE32(MAC, A, B, ...) MAC(A, B) BLUEGRASS_META_FE31(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA2(MAC,  A, B, ...) MAC(A, B), BLUEGRASS_META_FE1(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA3(MAC,  A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA2(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA4(MAC,  A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA3(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA5(MAC,  A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA4(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA6(MAC,  A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA5(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA7(MAC,  A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA6(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA8(MAC,  A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA7(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA9(MAC,  A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA8(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA10(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA9(MAC,  A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA11(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA10(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA12(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA11(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA13(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA12(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA14(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA13(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA15(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA14(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA16(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA15(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA17(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA16(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA18(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA17(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA19(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA18(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA20(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA19(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA21(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA20(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA22(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA21(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA23(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA22(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA24(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA23(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA25(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA24(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA26(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA25(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA27(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA26(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA28(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA27(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA29(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA28(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA30(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA29(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA31(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA30(MAC, A, ##__VA_ARGS__)
#define BLUEGRASS_META_FE_COMMA32(MAC, A, B, ...) MAC(A, B), BLUEGRASS_META_FE_COMMA31(MAC, A, ##__VA_ARGS__)

#define BLUEGRASS_META_FOREACH_NO_COMMA(MAC, D, ...) \
   BLUEGRASS_META_GET_NTH_ARG("ignored", ##__VA_ARGS__, \
      BLUEGRASS_META_FE32,BLUEGRASS_META_FE31,BLUEGRASS_META_FE30,BLUEGRASS_META_FE29,BLUEGRASS_META_FE28,BLUEGRASS_META_FE27,BLUEGRASS_META_FE26,BLUEGRASS_META_FE25,BLUEGRASS_META_FE24,BLUEGRASS_META_FE23,BLUEGRASS_META_FE22,BLUEGRASS_META_FE21,BLUEGRASS_META_FE20,BLUEGRASS_META_FE19,BLUEGRASS_META_FE18,BLUEGRASS_META_FE17,BLUEGRASS_META_FE16,BLUEGRASS_META_FE15,BLUEGRASS_META_FE14,BLUEGRASS_META_FE13,BLUEGRASS_META_FE12,BLUEGRASS_META_FE11,BLUEGRASS_META_FE10,BLUEGRASS_META_FE9,BLUEGRASS_META_FE8,BLUEGRASS_META_FE7,BLUEGRASS_META_FE6,BLUEGRASS_META_FE5,BLUEGRASS_META_FE4,BLUEGRASS_META_FE3,BLUEGRASS_META_FE2,BLUEGRASS_META_FE1,BLUEGRASS_META_FE0)(MAC, D, ##__VA_ARGS__)

#define BLUEGRASS_META_FOREACH(MAC, D, ...) \
   BLUEGRASS_META_GET_NTH_ARG("ignored", ##__VA_ARGS__, \
      BLUEGRASS_META_FE_COMMA32,BLUEGRASS_META_FE_COMMA31,BLUEGRASS_META_FE_COMMA30,BLUEGRASS_META_FE_COMMA29,BLUEGRASS_META_FE_COMMA28,BLUEGRASS_META_FE_COMMA27,BLUEGRASS_META_FE_COMMA26,BLUEGRASS_META_FE_COMMA25,BLUEGRASS_META_FE_COMMA24,BLUEGRASS_META_FE_COMMA23,BLUEGRASS_META_FE_COMMA22,BLUEGRASS_META_FE_COMMA21,BLUEGRASS_META_FE_COMMA20,BLUEGRASS_META_FE_COMMA19,BLUEGRASS_META_FE_COMMA18,BLUEGRASS_META_FE_COMMA17,BLUEGRASS_META_FE_COMMA16,BLUEGRASS_META_FE_COMMA15,BLUEGRASS_META_FE_COMMA14,BLUEGRASS_META_FE_COMMA13,BLUEGRASS_META_FE_COMMA12,BLUEGRASS_META_FE_COMMA11,BLUEGRASS_META_FE_COMMA10,BLUEGRASS_META_FE_COMMA9,BLUEGRASS_META_FE_COMMA8,BLUEGRASS_META_FE_COMMA7,BLUEGRASS_META_FE_COMMA6,BLUEGRASS_META_FE_COMMA5,BLUEGRASS_META_FE_COMMA4,BLUEGRASS_META_FE_COMMA3,BLUEGRASS_META_FE_COMMA2,BLUEGRASS_META_FE1,BLUEGRASS_META_FE0)(MAC, D, ##__VA_ARGS__)
